﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using EQEmu.Database;
using EQEmu.Database.Extensions;

namespace EQEmu.Spawns
{
    public class ZoneSpawnsDatabase : ZoneSpawns, IDisposable
    {
        private EQEmuContext _context = null;

        public ZoneSpawnsDatabase(string zone, EQEmuContextFactory factory,int zoneVersion=0)
            : base(zone,zoneVersion)
        {
            _context = factory.Create();
            var query = _context.spawn2.Where(x => zone == x.zone && ZoneVersion == x.version );
            foreach (var sp in query)
            {
                base.AddSpawn(sp);
            }
        }

        public override void AddSpawn(spawn2 spawn)
        {
            base.AddSpawn(spawn);
            _context.spawn2.AddObject(spawn);
        }

        public override spawn2 CreateSpawn()
        {
            var sp = _context.spawn2.CreateObject();
            sp.version = ZoneVersion;
            sp.zone = ZoneShortName;
            return sp;
        }

        public override void RemoveSpawn(spawn2 spawn)
        {
            base.RemoveSpawn(spawn);
            _context.spawn2.DeleteObject(spawn);
        }

        public void CommitChanges()
        {
            if (_context != null)
            {
                _context.SaveChanges();
            }
        }

        public override bool HasModifications
        {
            get
            {
                if (_context != null)
                {
                    return _context.ObjectStateManager
                        .GetObjectStateEntries(
                            System.Data.EntityState.Added | 
                            System.Data.EntityState.Deleted | 
                            System.Data.EntityState.Modified).Any();
                }
                else return false;
            }
        }

        public static ZoneSpawnsDatabase LoadFromFile(string path, EQEmuContextFactory factory)
        {
            ZoneSpawnsDatabase zp = null;
            string zone = "";
            int version = GetVersionFromFileName(path);
            var spawns = (IEnumerable<spawn2>)(SerializationExtensions.FromXmlFile<spawn2[]>(path));
            if (spawns.Count() > 0)
            {
                zone = spawns.ElementAt(0).zone;
            }

            zp = new ZoneSpawnsDatabase(zone, factory, version);
            foreach (var sp in spawns.ToArray())
            {
                var exists = zp.Spawns.FirstOrDefault(x => x.id == sp.id);
                if (exists != null)
                {
                    exists.CopyFrom(sp);
                }
                else
                {
                    zp.AddSpawn(sp);
                }
            }

            return zp;
        }

        protected virtual void Dispose(bool disposeAll)
        {
            if (_context != null)
            {
                _context.Dispose();
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }
    }
}
